package com.xcity.game.activity2.groupbuy;

import java.io.File;
import java.util.Queue;

import org.slf4j.Logger;

import com.alibaba.fastjson.TypeReference;
import com.xcity.config.ConfigEx;
import com.xcity.db.entity.Player;
import com.xcity.game.activity2.groupbuy.model.BoughtRecord;
import com.xcity.game.activity2.groupbuy.model.GroupBuyData;
import com.xcity.game.activity2.groupbuy.template.GroupBuyConfig;
import com.xcity.game.activity2.groupbuy.template.GroupBuyTemplate.Discount;
import com.xcity.game.common.Cause;
import com.xcity.game.common.MessageConst;
import com.xcity.game.common.PlayerPool;
import com.xcity.game.mail.MailAttach;
import com.xcity.game.mail.MailService;
import com.xcity.game.player.cache.PlayerCacheService;

import gnu.trove.map.TIntObjectMap;
import naga.x.App;
import naga.x.game.GameUnit;
import naga.x.game.time.TimeUpdater;
import naga.x.util.IOUtils;
import naga.x.util.IOUtils.LineReaderListener;
import naga.x.util.NumberUtils;

public class GroupBuyUtils {
	
	private static final Logger LOG = GameUnit.LOG;
	
	public static int activitySerial = -1;
	
	public static GroupBuyData get(Player player, boolean create) {
		GroupBuyData data = player.getPool().getObject(PlayerPool.PROPERTY_GROUP_BUY_DATA, new TypeReference<GroupBuyData>() {});
		if (data == null && create) {
			data = new GroupBuyData(activitySerial, TimeUpdater.getInstance().today());
			player.poolSet(PlayerPool.PROPERTY_GROUP_BUY_DATA, data);
		}
		return data;
	}
	
	/**
	 * 积分、团购券、购买记录清零
	 * @param player
	 * @param serial 当前活动序列号
	 */
	public static void clear(Player player, int serial) {
		GroupBuyData data = get(player, false);
		if (data == null) {
			return;
		}
		if (serial != data.serial) { // 活动更新
			player.poolRemove(PlayerPool.PROPERTY_GROUP_BUY_DATA);
			return;
		}
		if (data.lastBuyDay != TimeUpdater.getInstance().today()) { // 每天只需重置购买记录
			data.lastBuyDay = TimeUpdater.getInstance().today();
			data.records = null;
		}
	}

	/** 获取团购积分 */
	public static int getScore(Player player) {
		GroupBuyData data = get(player, false);
		return data != null ? data.score : 0;
	}
	
	/** 加团购积分 */
	public static boolean addScore(Player player, int value, String cause) {
		GroupBuyData data = get(player, true);
		return addScore(player, data, value, cause);
	}
	
	public static boolean addScore(Player player, GroupBuyData data, int value, String cause) {
		int oldVal = data.score;
		if (value <= 0 || oldVal + value <= 0) {
			return false;
		}
		data.score += value;
		LOG.info("[ADD GPB SCORE]ID[{}]OLD[{}]NEW[{}]CAUSE[{}]", player.getId(), oldVal, data.score, cause);
		return true;
	}
	
	
//	public static boolean decScore(Player player, int value, String cause) {
//		int oldVal = player.getPool().getIntValue(PlayerPool.PROPERTY_GROUP_BUY_SCORE);
//		if (value <= 0 || value > oldVal) {
//			return false;
//		}
//		int newVal = oldVal - value;
//		player.poolSet(PlayerPool.PROPERTY_GROUP_BUY_SCORE, newVal);
//		LOG.info("[DEC GPB SCORE]ID[{}]OLD[{}]NEW[{}]CAUSE[{}]", player.getId(), oldVal, newVal, cause);
//		return true;
//	}
	
	/** 获取团购券数量 */
	public static int getCoupon(Player player) {
		GroupBuyData data = get(player, false);
		return data != null ? data.coupon : 0;
	}
	
	/** 加团购券 */
	public static boolean addCoupon(Player player, int value, String cause) {
		GroupBuyData data = get(player, true);
		return addCoupon(player, data, value, cause);
	}
	
	public static boolean addCoupon(Player player, GroupBuyData data, int value, String cause) {
		int oldVal = data.coupon;
		if (value <= 0 || oldVal + value <= 0) {
			return false;
		}
		data.coupon += value;
		LOG.info("[ADD GPB COUPON]ID[{}]OLD[{}]NEW[{}]CAUSE[{}]", player.getId(), oldVal, data.coupon, cause);
		return true;
	}
	
	/** 减团购券 */
	public static boolean decCoupon(Player player, int value, String cause) {
		GroupBuyData data = get(player, true);
		return decCoupon(player, data, value, cause);
	}
	
	public static boolean decCoupon(Player player, GroupBuyData data, int value, String cause) {
		int oldVal = data.coupon;
		if (value <= 0 || value > oldVal) {
			return false;
		}
		data.coupon -= value;
		LOG.info("[DEC GPB COUPON]ID[{}]OLD[{}]NEW[{}]CAUSE[{}]", player.getId(), oldVal, data.coupon, cause);
		return true;
	}
	
//	/** 获取团购记录 */
//	public static BoughtRecord getBoughtRecord(Player player, int id) {
//		GroupBuyData data = get(player, false);
//		return data != null ? data.getRecord(id) : null;
//	}
	
	/** 团购成功，记录、返券、返积分 */
	public static BoughtRecord fireBought(Player player, int id, int couponUsed, int stoneUsed) {
		GroupBuyData data = get(player, true);
//		BoughtRecord br = data.getOrCreateRecord(id);
		BoughtRecord br = data.newRecord(id);
		
//		br.boughtNum += 1;
//		br.couponUsed += couponUsed;
//		br.stoneUsed += stoneUsed;
		br.couponUsed = couponUsed;
		br.stoneUsed = stoneUsed;
		int coupon = stoneUsed / GroupBuyConfig.returnCouponRatio;
		if (coupon > 0) { // 返券
			addCoupon(player, data, coupon, Cause.GROUP_BUY);
		}
		int score = stoneUsed / GroupBuyConfig.returnScoreRatio;
		if (score > 0) { // 返积分
			addScore(player, data, score, Cause.GROUP_BUY);
		}
		return br;
	}
	
	public static void flushBuyQueue(Queue<Long> queue) {
		if (queue.isEmpty()) {
			return;
		}
		ConfigEx config = App.getApp().getConfig();
		File file = new File(config.localDbDir, "groupBuy.db");
		Long id;
		StringBuilder builder = new StringBuilder(1024);
		while ((id = queue.poll()) != null) {
			builder.append(id).append("\n");
		}
		IOUtils.write(file, builder.toString(), IOUtils.UTF8, true);
	}
	
	public static void doReturnStone(final Logger logger, final TIntObjectMap<Discount> discounts) {
		ConfigEx config = App.getApp().getConfig();
		File file = new File(config.localDbDir, "groupBuy.db");
		if (!file.exists()) {
			return;
		}
		final PlayerCacheService pcs = App.getApp().getServiceManager().get(PlayerCacheService.class);
		final MailService ms = App.getApp().getServiceManager().get(MailService.class);
		IOUtils.read(file, IOUtils.UTF8, new LineReaderListener() {
			@Override
			public boolean readLine(String line) {
				long id = NumberUtils.parseLong(line);
				try {
					Player player = pcs.find(id);
					if (player == null)
						return true;
					GroupBuyData data = GroupBuyUtils.get(player, false);
//					Set<Entry<Integer, BoughtRecord>> set = data.records.entrySet();
					int stone = 0;
//					for (Entry<Integer, BoughtRecord> e : set) {
//						BoughtRecord br = e.getValue();
//						// 该商品最终折扣
//						Discount discount = discounts.get(e.getKey());
//						// 计算返钻数
//						int n = br.stoneUsed - br.boughtNum * discount.price;
//						if (n > 0) {
//							stone += n;
//						}
//					}
					if (data.records != null) {
						for (BoughtRecord br : data.records) {
							// 该商品最终折扣
							Discount discount = discounts.get(br.id);
							// 计算返钻数
							int n = br.stoneUsed - discount.price;
							if (n > 0) {
								stone += n;
							}
						}
					}
					
					if (stone > 0) {
						ms.sendSystemMail(id,
								MessageConst.ACTIVITY_GROUP_BUY_RETURN_STONE_MAIL_TITLE,
								MessageConst.ACTIVITY_GROUP_BUY_RETURN_STONE_MAIL_CONTENT,
								new MailAttach(0, stone));
					}
					logger.info("[GROUPBUY REBATE]ID[{}]STONE[{}]", id, stone);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
				}
				return true;
			}
		});
		IOUtils.deleteFile(file);
	}
	
	
}
